package br.ita.comp.ces22.quiz.web.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import br.ita.comp.ces22.quiz.domain.Question;
import br.ita.comp.ces22.quiz.domain.Quiz;
import br.ita.comp.ces22.quiz.domain.QuizKey;
import br.ita.comp.ces22.quiz.domain.User;

public class QuizAction extends Action{
	private DynaActionForm quizForm;
	private HttpSession quizSession;
	private HttpServletRequest quizRequest;
	private User user;

	public QuizAction() {
		new ActionDaoManager();
	}
	
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
			throws Exception {		

		try {
			setQuizForm((DynaActionForm) form);
			setQuizSession(request.getSession());
			setQuizRequest(request);

			setUser(ActionDaoManager.getUserDao().getById(
				(String) quizSession.getAttribute("loggedUser")));

			if (quizForm.get("next").equals("Novo Quiz")) { 		  
				ArrayList questionList = getRandomQuestionList();		  
				return startNewQuiz(mapping, questionList);			  
			} 
			else if (quizForm.get("next").equals("Seguir")){
				HashMap mMap;	    	
				if (quizSession.getAttribute("map") != null)
					mMap = (HashMap)quizSession.getAttribute("map");
				else 
					mMap = new HashMap<Integer, Integer>();

				saveAnswer(mMap); 	    	  	
				ArrayList questionList = getQuestionList();	

				if ((questionList != null) && (questionList.size() > 0))
					return goToNextoQuestion(mapping, questionList);   	  	

				return endQuiz(mapping,mMap);   	
			} 
			else return null;
		}
		catch (RuntimeException e){		
				HashMap mMap;
				if (quizSession.getAttribute("map")!=null)
					mMap = (HashMap) quizSession.getAttribute("map");
				else
					mMap = new HashMap<Integer, Integer>();
				return restartQuiz(mapping,mMap);
		}
	}

	private ArrayList<Question> getRandomQuestionList(){
		ArrayList<Question> questionList = 
			(ArrayList<Question>) ActionDaoManager.getQuizDao().getRandomQuestions(user);
		return questionList;
	}
	
	private ActionForward startNewQuiz(ActionMapping mapping, ArrayList questionList){	  
		if (questionList != null){

			quizSession.setAttribute("questionList", questionList);
			quizSession.setAttribute("idquestion", ((Question)questionList.get(0)).
					getIdQuestion());
			ArrayList<String> altList = getAlternativeList(questionList);
			quizRequest.setAttribute("altList", altList);
			quizRequest.setAttribute("question", ((Question)questionList.get(0)).
					getQuestion());
			return mapping.findForward("next");  
		} 

		quizRequest.setAttribute("overflow", "1");
		return mapping.findForward("success");
	}
	
	private ArrayList<String> getAlternativeList(ArrayList questionList){
		ArrayList<String> alternativeList = new ArrayList<String>();
		alternativeList.add(((Question)questionList.get(0)).getAlternative1());
		alternativeList.add(((Question)questionList.get(0)).getAlternative2());
		alternativeList.add(((Question)questionList.get(0)).getAlternative3());
		alternativeList.add(((Question)questionList.get(0)).getAlternative4());
		alternativeList.add(((Question)questionList.get(0)).getAlternative5());
		return alternativeList;      
	}
	
	private void saveAnswer(HashMap mMap) throws Exception{
			Integer m = (Integer) quizSession.getAttribute("idquestion");
			Integer n = Integer.valueOf(Integer.parseInt((String)quizForm.
				get("alternative")));
			mMap.put(m, n);
			quizSession.setAttribute("map", mMap);
	}
	
	private ActionForward goToNextoQuestion(ActionMapping mapping, ArrayList questionList){
		quizSession.setAttribute("questionList", questionList);
		quizSession.setAttribute("idquestion", ((Question)questionList.get(0)).getIdQuestion());
		quizRequest.setAttribute("question", ((Question)questionList.get(0)).getQuestion());
		ArrayList<String> altList = getAlternativeList(questionList);
		quizRequest.setAttribute("altList", altList);
		return mapping.findForward("next");
	}
	
	private ActionForward endQuiz(ActionMapping mapping, HashMap mMap){
		Iterator it = mMap.entrySet().iterator();
		int points = 0;
		while (it.hasNext()) {

			Map.Entry pairs = (Map.Entry)(Map.Entry)it.next();
			Integer alternative = (Integer) pairs.getValue();
			Integer idQuestion = (Integer) pairs.getKey();
			Question question = ActionDaoManager.getQuestionDao().getById(idQuestion);

			Quiz mQuiz = new Quiz();
			QuizKey mQuizKey = new QuizKey();
			if (question.getRightAns().intValue() == alternative.intValue()) {
				mQuiz.setHit(new Integer(1));
				++points;
			} else {
				mQuiz.setHit(new Integer(0));
			}
			mQuizKey.setIdQuestion(idQuestion);
			mQuizKey.setLogin((String)quizSession.getAttribute("loggedUser"));
			mQuiz.setQk(mQuizKey);
			ActionDaoManager.getQuizDao().insert(mQuiz);
		}

		quizSession.setAttribute("points", Integer.valueOf(points));
		return mapping.findForward("success");
	}
	
	private ActionForward restartQuiz(ActionMapping mapping, HashMap mMap){
		return mapping.findForward("error");
	}

	private ArrayList getQuestionList(){
		ArrayList questionList = (ArrayList) quizSession.getAttribute("questionList");
		if (questionList != null) {
			questionList.remove(0);
		}
		return questionList;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public User getUser() {
		return user;
	}

	public void setQuizForm(DynaActionForm quizForm) {
		this.quizForm = quizForm;
	}

	public void setQuizRequest(HttpServletRequest quizRequest) {
		this.quizRequest = quizRequest;
	}

	public void setQuizSession(HttpSession quizSession) {
		this.quizSession = quizSession;
	}
}